package lc.q201_250;

import java.util.Arrays;

/**
 * 给定一个字符串 s，你可以通过在字符串前面添加字符将其转换为回文串。找到并返回可以用这种方式转换的最短回文串。
 *
 * 本质是求自身与反转串的最长匹配
 *
 * KMP算法
 *
 * @author lgb
 * @date 2020/08/29
 **/
public class Q214 {


    public String shortestPalindrome(String s) {
        int n = s.length();
        int[] fail = new int[n];// 前缀后缀交集最长字符串长度
        Arrays.fill(fail, -1);
        for (int i = 1; i < n; ++i) {
            int j = fail[i - 1];
            while (j != -1 && s.charAt(j + 1) != s.charAt(i)) {
                j = fail[j];
            }
            if (s.charAt(j + 1) == s.charAt(i)) {
                fail[i] = j + 1;
            }
        }
        int best = -1;
        for (int i = n - 1; i >= 0; --i) {
            while (best != -1 && s.charAt(best + 1) != s.charAt(i)) {
                best = fail[best];
            }
            if (s.charAt(best + 1) == s.charAt(i)) {
                ++best;
            }
        }
        String add = (best == n - 1 ? "" : s.substring(best + 1));
        StringBuffer ans = new StringBuffer(add).reverse();
        ans.append(s);
        return ans.toString();
    }



    public static void main(String[] args) {
        Q214 q214 = new Q214();
        String palindrome = q214.shortestPalindrome("abcd");
        System.out.println(palindrome);
    }

}
